package com.gopay.bis.service.bank.impl.ebank;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.BisPayCheckUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.bis.common.util.constants.BisPayConstants;
import com.gopay.bis.manager.bank.ebank.HxbcB2cManager;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.HxbcConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.hxbc.ebank.geturl.res.HXEB2CResGetUrl;
import com.gopay.common.domain.bank.hxbc.ebank.pay.req.BodyB2CReqPay;
import com.gopay.common.domain.bank.hxbc.ebank.pay.req.HXEB2CReqPay;
import com.gopay.common.domain.bank.hxbc.ebank.pay.res.BackVerifyB2CResPay;
import com.gopay.common.domain.bank.hxbc.ebank.pay.res.ForeVerifyB2CResPay;
import com.gopay.common.domain.bank.hxbc.ebank.query.req.HXEB2CReqQuery;
import com.gopay.common.domain.bank.hxbc.ebank.query.res.BodyB2CResQuery;
import com.gopay.common.domain.bank.hxbc.ebank.query.res.HXEB2CResQuery;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * 华夏E商宝B2C业务实现
 * 
 * HxbcB2cBankServiceImpl.java
 * 
 * @author LiLiLi
 */
public class HxbcB2cBankServiceImpl implements BankInteractRemoteService {

	private static Logger logger = LoggerFactory.getLogger(HxbcB2cBankServiceImpl.class);
	
	@Resource(name = "hxbcB2cManager")
	private HxbcB2cManager hxbcB2cManager;
	
	@Override
	public Result pay(BaseMessage base) {
		Result result = new Result(false);
		try {
			HXEB2CReqPay messageB2C = new HXEB2CReqPay();
			BeanUtils.copyProperties(base, messageB2C);
			BodyB2CReqPay bodyMessage = new BodyB2CReqPay();
			bodyMessage.setOrderNo(base.getOrderId());
			bodyMessage.setOrderAmt(TransUtils.amountConvert2Fen(base
					.getAmount().toString()));
			messageB2C.setBody(bodyMessage);
			HXEB2CResGetUrl messageUrl = new HXEB2CResGetUrl();
			BeanUtils.copyProperties(base, messageUrl);
			messageUrl = hxbcB2cManager.buildSign(messageB2C);
			messageUrl.setOrderId(base.getOrderId());
			messageUrl.setBankOrderId(base.getBankOrderId());
			messageUrl.setBankBusProd(base.getBankBusProd());
			messageUrl.setBankIntrChann(base.getBankIntrChann());
			messageUrl.setBank(base.getBank());
			messageUrl.setAmount(base.getAmount());
			result.setDefaultModel(messageUrl);
			result.setSuccess(true);
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		return result;
	}

	@Override
	public Result bankBack(BaseMessage base) {
		Result result = new Result(false);
		String payStatus = null;
		String orderId=null;
		String orderAmt=null;
		try {
			HXEB2CReqPay reqPay = new HXEB2CReqPay();
			BeanUtils.copyProperties(base, reqPay);
            
			if (!reqPay.isFront()) {
				BackVerifyB2CResPay resPay = hxbcB2cManager.backVerify(reqPay);
				result.setDefaultModel(resPay != null ? true : false);
				orderId=resPay.getBody().getSic().getHXE().getBody()
						.getOrderNo();
				orderAmt=resPay.getBody().getSic().getHXE().getBody().getOrderAmt();
				/**
				 * 金额转化成元
				 */
				orderAmt=TransUtils.amountConvert2Yuan(orderAmt.toString());
				/**
				 * 华夏银行返回订单状态0：成功；1：失败；2：未知
				 */
				payStatus = resPay.getBody().getSic().getHXE().getBody()
						.getStatus();
				resPay.setOrderId(orderId);
				resPay.setBankOrderId(orderId);
				result.setModel("res", resPay);
				result.setSuccess(true);
			} else if (reqPay.isFront()) {
				ForeVerifyB2CResPay resPay = hxbcB2cManager.foreVerify(reqPay);
				result.setDefaultModel(resPay != null ? true : false);
				logger.info("从明文中获取订单号为：OrderId==="+resPay.getBody().getSic().getHXE().getBody()
						.getOrderNo());
				orderId=resPay.getBody().getSic().getHXE().getBody()
						.getOrderNo();
				orderAmt=resPay.getBody().getSic().getHXE().getBody().getOrderAmt();
				/**
				 * 金额转化成元
				 */
				orderAmt=TransUtils.amountConvert2Yuan(orderAmt.toString());
				/**
				 * 华夏银行返回订单状态0：成功；1：失败；2：未知
				 */
				payStatus = resPay.getBody().getSic().getHXE().getBody()
						.getStatus();
				resPay.setBankOrderId(orderId);
				resPay.setFront(true);
				resPay.setOrderId(orderId);
				result.setModel("res", resPay);
				result.setSuccess(true);
			}
			if (result.isSuccess() && (Boolean) result.getDefaultModel()
					&& payStatus.equals(HxbcConstants.TRADE_SUCCESS)) {
				// 验签成功入账
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", orderId);
				param.put("amt", orderAmt.toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "00");
				param.put("retCode", "00");
				param.put("retMsg", "验签成功");
				param.put("signData", reqPay.getSignMessage());
				param.put("isFront", String.valueOf(reqPay.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(true);
			} else {
				// 通知后台地址该订单失败
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", orderId);
				param.put("amt", null == orderAmt ? "" : orderAmt.toString());
				param.put("cardType", "Unknown");
				param.put("notifyNum", "1");
				param.put("payStatus", "01");
				param.put("retCode", "01");
				param.put("retMsg", "验签失败!");
				param.put("signData", reqPay.getSignMessage());
				param.put("isFront", String.valueOf(reqPay.isFront()));
				result.setModel("isNotifyCashier", param);
				result.setOrderStatus(false);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6064);
		}
		logger.info("返回result==="+result.toString());
		return result;
	}

	@Override
	public Result query(BaseMessage base) {
		Result result = new Result(false);
		try {
			HXEB2CReqQuery reqQuery = new HXEB2CReqQuery();
			BeanUtils.copyProperties(base, reqQuery);
			HXEB2CResQuery resQuery = hxbcB2cManager.query(reqQuery);
			result.setDefaultModel(resQuery);
			result.setSuccess(true);
			if (BisPayCheckUtils.checkExternalOrderID(base.getOrderId())) {
				Map<String, String> param = new HashMap<String, String>();
				param.put("orderId", base.getOrderId());
				param.put("amount", base.getAmount().toString());
				if (resQuery == null) {
					// 查询订单为空
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", "银行返回对账结果为空");
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				if (resQuery.getHead().getRespCode()
						.equals(HxbcConstants.RESPCODE_OTHER)) {
					// 查询订单错误
					param.put("returnCode", BisPayConstants.QUERYSTATE_FAIL);
					param.put("returnMessage", resQuery.getHead()
							.getRespDescp());
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					result.setModel("queryResult", param);
					return result;
				}
				if (resQuery.getHead().getRespCode() != null
						&& !resQuery.getHead().getRespCode().equals("")) {
					// 有可能是订单号错或者其他错误，滞后处理
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					if (resQuery.getHead().getRespCode()
							.equals(HxbcConstants.RESPCODE_NOTFOUND)) {
						param.put("tradeState",
								BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "未成功支付或订单不存在或其他错误");
					}
					// 订单处理中
					else if (resQuery.getHead().getRespCode()
							.equals(HxbcConstants.RESPCODE_PROSESSING)) {
						param.put("tradeState",
								BisPayConstants.TRADESTATE_OTHER);
						param.put("returnMessage", "订单正在处理中");
					}
					// 订单处理完成
					else {
						BodyB2CResQuery resMsg = resQuery.getBody();
						if (StringUtils.isEmpty(resMsg.getStatus())) {
							param.put("tradeState",
									BisPayConstants.TRADESTATE_OTHER);
							param.put("returnMessage", resQuery.getHead()
									.getRespDescp());
						}
						// 订单状态成功(订单已支付)
						if (HxbcConstants.TRADE_SUCCESS.equals(resMsg
								.getStatus())) {
							param.put("tradeState",
									BisPayConstants.TRADESTATE_SUCCESS);
							param.put("returnMessage", "交易成功");
						} else if (HxbcConstants.TRADE_FAIL.equals(resMsg
								.getStatus())) {
							param.put("tradeState",
									BisPayConstants.TRADESTATE_FAIL);
							param.put("returnMessage", "交易失败");
						} else {
							param.put("tradeState",
									BisPayConstants.TRADESTATE_OTHER);
							param.put("returnMessage", resQuery.getHead()
									.getRespDescp());
						}
					}
				} else {
					param.put("returnCode", BisPayConstants.QUERYSTATE_SUCCESS);
					param.put("tradeState", BisPayConstants.TRADESTATE_OTHER);
					param.put("returnMessage", "银行返回订单未查到");
				}
				result.setModel("queryResult", param);
			}
		} catch (GopayException e) {
			BankLogUtils.printServiceImplExceptionLog(e);
			result.setResultCode(e.getErrCode());
		} catch (Exception ex) {
			BankLogUtils.printServiceImplExceptionLog(ex);
			result.setResultCode(ProcCodeConstants.PROC_CODE_100E6033);
		}
		return result;
	}

	@Override
	public Result refund(BaseMessage base) {
		return null;
	}

	@Override
	public Result dayend(BaseMessage base) {
		return null;
	}

	@Override
	public Result queryBack(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

    @Override
    public Result refundBack(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public Result refundQuery(BaseMessage base) {
        // TODO Auto-generated method stub
        return null;
    }

	@Override
	public Result sendBankRefund(BaseMessage base) {
		// TODO Auto-generated method stub
		return null;
	}

}
